class EventEmitter {
    constructor() {
        this.events = {};
    }

    on(name, cb) {
        let cbs = this.events[name] || [];
        cbs.push(cb);
        this.events[name] = cbs;
        return this;
    }

    off(name, cb) {
        let cbs = this.events[name] || [];
        cbs = cbs.length > 0 && cbs.filter(fn => fn != cb);
        this.events[name] = cbs;
        return this;
    }

    emit(name) {
        let cbs = this.events[name] || [];
        cbs.forEach(fn => fn());

        return this;
    }

    once(name, cb) {
        const wrapped = (...args) => {
            cb(...args);
            this.off(name, wrapped)
        }

        this.on(name, wrapped)
        return this;
    }
}